<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>字符串与十六进制转换工具</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f9f9f9;
        }
.pagination {
    margin-top: 20px;
    display: flex;
    justify-content: center;
    gap: 10px;
}

.pagination button {
    padding: 8px 16px;
    background-color: #3498db;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

.pagination button:hover {
    background-color: #2980b9;
}

.pagination button:disabled {
    background-color: #95a5a6;
    cursor: not-allowed;
}

.pagination span {
    padding: 8px 16px;
    align-self: center;
}
        .container {
            background-color: white;
            padding: 25px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            margin-bottom: 20px;
        }

        h1, h2 {
            color: #2c3e50;
            margin-top: 0;
        }

        label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
        }

        textarea {
            width: 100%;
            height: 120px;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-family: inherit;
            font-size: 16px;
            resize: vertical;
            margin-bottom: 15px;
        }

        .button-group {
            margin-bottom: 20px;
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
        }

        button {
            padding: 10px 18px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
        }

        .convert-btn {
            background-color: #3498db;
            color: white;
        }

        .convert-btn:hover {
            background-color: #2980b9;
        }

        .translate-btn {
            background-color: #9b59b6;
            color: white;
        }

        .translate-btn:hover {
            background-color: #8e44ad;
        }

        .copy-btn {
            background-color: #2ecc71;
            color: white;
        }

        .copy-btn:hover {
            background-color: #27ae60;
        }

        .delete-btn {
            background-color: #e74c3c;
            color: white;
        }

        .delete-btn:hover {
            background-color: #c0392b;
        }

        #result {
            margin-top: 20px;
            padding: 15px;
            background-color: #f8f9fa;
            border-radius: 4px;
            border-left: 4px solid #3498db;
        }

        .result-content {
            margin-bottom: 15px;
            white-space: pre-line;
        }

        .history-item {
            padding: 15px;
            margin-bottom: 15px;
            background-color: white;
            border-radius: 4px;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
            position: relative;
        }

        .history-item-actions {
            margin-top: 10px;
            display: flex;
            gap: 10px;
        }

        .copy-message {
            position: absolute;
            right: 15px;
            top: 15px;
            background-color: #2ecc71;
            color: white;
            padding: 3px 8px;
            border-radius: 3px;
            font-size: 12px;
            display: none;
            animation: fadeIn 0.3s;
        }

        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }

        .no-history {
            text-align: center;
            color: #7f8c8d;
            padding: 20px;
        }

        .error-message {
            color: #e74c3c;
            font-weight: bold;
        }

        .mode-indicator {
            margin-bottom: 15px;
            padding: 8px;
            background-color: #f0f0f0;
            border-radius: 4px;
            font-weight: bold;
        }

        .mode-convert {
            border-left: 4px solid #3498db;
        }

        .mode-translate {
            border-left: 4px solid #9b59b6;
        }
    </style>
</head>
<body>
<div class="container">
    <h1>字符串与十六进制转换工具</h1>

    <div class="mode-indicator mode-convert" id="modeIndicator">
        当前模式: 字符串转十六进制
    </div>

    <div>
        <label for="inputString">输入内容:</label>
        <textarea id="inputString" placeholder="请输入要转换的字符串或十六进制..."></textarea>
    </div>

    <div class="button-group">
        <button class="convert-btn" onclick="convertToHex()">转换为十六进制</button>
        <button class="translate-btn" onclick="translateFromHex()">翻译为字符串</button>
    </div>

    <div id="result">
        <p>转换结果将显示在这里...</p>
    </div>
</div>

<div class="container">
    <h2>转换历史记录</h2>
    <div id="historyList">
        <p class="no-history">暂无历史记录</p>
    </div>
</div>

<script>
    // 当前模式: 'convert' 或 'translate'
    let currentMode = 'convert';

    // 更新模式指示器
    function updateModeIndicator() {
        const indicator = document.getElementById('modeIndicator');
        if (currentMode === 'convert') {
            indicator.className = 'mode-indicator mode-convert';
            indicator.textContent = '当前模式: 字符串转十六进制';
            document.getElementById('inputString').placeholder = '请输入要转换的字符串...';
        } else {
            indicator.className = 'mode-indicator mode-translate';
            indicator.textContent = '当前模式: 十六进制转字符串';
            document.getElementById('inputString').placeholder = '请输入要翻译的十六进制...';
        }
    }

    // 转换函数
    function convertToHex() {
        currentMode = 'convert';
        updateModeIndicator();

        const inputString = document.getElementById('inputString').value.trim();
        const resultDiv = document.getElementById('result');

        if (!inputString) {
            resultDiv.innerHTML = '<p class="error-message">请输入要转换的字符串</p>';
            return;
        }

        resultDiv.innerHTML = '<p>转换中...</p>';

        fetch('/tool/tohex', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ input_string: inputString })
        })
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应不正常');
            }
            return response.json();
        })
        .then(data => {
            if (data.hex_string) {
                resultDiv.innerHTML = `
                    <div class="result-content">
                        <p><strong>原始字符串:</strong> ${escapeHtml(inputString)}</p>
                        <p><strong>十六进制结果:</strong> ${escapeHtml(data.hex_string)}</p>
                    </div>
                    <button class="copy-btn" onclick="copyToClipboard('${escapeHtml(data.hex_string)}', event)">复制结果</button>
                    <span class="copy-message">已复制!</span>
                `;
                loadHistory();
            } else if (data.error) {
                resultDiv.innerHTML = `<p class="error-message">错误: ${escapeHtml(data.error)}</p>`;
            }
        })
        .catch(error => {
            resultDiv.innerHTML = `<p class="error-message">请求失败: ${escapeHtml(error.message)}</p>`;
            console.error('转换错误:', error);
        });
    }

    // 翻译函数（十六进制转字符串）
    function translateFromHex() {
        currentMode = 'translate';
        updateModeIndicator();

        const inputHex = document.getElementById('inputString').value.trim();
        const resultDiv = document.getElementById('result');

        if (!inputHex) {
            resultDiv.innerHTML = '<p class="error-message">请输入要翻译的十六进制</p>';
            return;
        }

        resultDiv.innerHTML = '<p>翻译中...</p>';

        fetch('/tool/translate', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ hex_string: inputHex })
        })
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应不正常');
            }
            return response.json();
        })
        .then(data => {
            if (data.translated_string) {
                const translatedWithBreaks = escapeHtml(data.translated_string).replace(/\n/g, '<br>');
                resultDiv.innerHTML = `
                    <div class="result-content">
                        <p><strong>原始十六进制:</strong> ${escapeHtml(inputHex)}</p>
                        <p><strong>翻译结果:</strong> ${escapeHtml(data.translated_string)}</p>
                    </div>
                    <button class="copy-btn" onclick="copyToClipboard('${escapeHtml(data.translated_string)}', event)">复制结果</button>
                    <span class="copy-message">已复制!</span>
                `;
                loadHistory();
            } else if (data.error) {
                resultDiv.innerHTML = `<p class="error-message">错误: ${escapeHtml(data.error)}</p>`;
            }
        })
        .catch(error => {
            resultDiv.innerHTML = `<p class="error-message">请求失败: ${escapeHtml(error.message)}</p>`;
            console.error('翻译错误:', error);
        });
    }

    // 复制到剪贴板函数
    function copyToClipboard(text, event) {
        // 使用现代API或备用方法
        navigator.clipboard.writeText(text).then(() => {
            showCopyMessage(event);
        }).catch(err => {
            alert('复制失败，请手动复制');
            fallbackCopy(text, event);
        });
    }

    // 备用复制方法
    function fallbackCopy(text, event) {
        const textarea = document.createElement('textarea');
        textarea.value = text;
        document.body.appendChild(textarea);
        textarea.select();

        try {
            const successful = document.execCommand('copy');
            if (successful) {
                showCopyMessage(event);
            } else {
                alert('复制失败，请手动选择文本后复制');
            }
        } catch (err) {
            console.error('复制失败:', err);
            alert('复制失败，请手动选择文本后复制');
        }

        document.body.removeChild(textarea);
    }

    // 显示复制成功消息
    function showCopyMessage(event) {
        const message = event.target.nextElementSibling;
        if (message && message.classList.contains('copy-message')) {
            message.style.display = 'block';
            setTimeout(() => {
                message.style.display = 'none';
            }, 2000);
        }
    }

    // 删除历史记录
    function deleteHistory(id, event) {
        if (!confirm('确定要删除这条记录吗？')) {
            return;
        }

        const historyItem = event.target.closest('.history-item');
        historyItem.style.opacity = '0.5';
        historyItem.style.pointerEvents = 'none';

        fetch(`/tool/history/${id}/`, {
            method: 'DELETE',
            headers: {
                'Content-Type': 'application/json',
            }
        })
        .then(response => {
            if (response.ok) {
                historyItem.remove();

                // 检查是否还有历史记录
                if (document.querySelectorAll('.history-item').length === 0) {
                    document.getElementById('historyList').innerHTML = '<p class="no-history">暂无历史记录</p>';
                }
            } else {
                historyItem.style.opacity = '1';
                historyItem.style.pointerEvents = 'auto';
                alert('删除失败');
            }
        })
        .catch(error => {
            console.error('删除错误:', error);
            historyItem.style.opacity = '1';
            historyItem.style.pointerEvents = 'auto';
            alert('删除时出错');
        });
    }

let currentPage = 1;
let totalPages = 1;

async function loadHistory(page = 1) {
try {
    const response = await fetch(`/tool/history/?page=${page}`);
    if (!response.ok) throw new Error('获取历史记录失败');

    const data = await response.json();

    // 更新分页信息
    currentPage = page;
    totalPages = Math.ceil(data.count / data.page_size);

    // 渲染数据
    renderHistory(data.results);
    updatePaginationUI(data);

} catch (error) {
    console.error('加载历史记录错误:', error);
    document.getElementById('historyList').innerHTML = `
        <p class="error-message">加载失败: ${escapeHtml(error.message)}</p>
    `;
}
}

function renderHistory(items) {
const historyList = document.getElementById('historyList');

if (items.length > 0) {
    let html = items.map(item => `
        <div class="history-item">
            <p><strong>${item.type === 'translate' ? '原始十六进制' : '原始字符串'}:</strong>
               ${escapeHtml(item.original_string)}</p>
            <p><strong>${item.type === 'translate' ? '翻译结果' : '十六进制'}:</strong>
               ${escapeHtml(item.hex_string)}</p>
            <p><small>${new Date(item.created_at).toLocaleString()}</small></p>
            <div class="history-item-actions">
                <button class="copy-btn" onclick="copyToClipboard('${escapeHtml(item.hex_string)}', event)">
                    复制
                </button>
                <button class="delete-btn" onclick="deleteHistory(${item.id}, event)">删除</button>
            </div>
        </div>
    `).join('');

    historyList.innerHTML = html;
} else {
    historyList.innerHTML = '<p class="no-history">暂无历史记录</p>';
}
}

function updatePaginationUI(data) {
const paginationDiv = document.createElement('div');
paginationDiv.className = 'pagination';

// 上一页按钮
if (data.previous) {
    const prevBtn = document.createElement('button');
    prevBtn.textContent = '上一页';
    prevBtn.onclick = () => loadHistory(currentPage - 1);
    paginationDiv.appendChild(prevBtn);
}

// 页码信息
const pageInfo = document.createElement('span');
pageInfo.textContent = `第 ${currentPage} 页 / 共 ${totalPages} 页`;
paginationDiv.appendChild(pageInfo);

// 下一页按钮
if (data.next) {
    const nextBtn = document.createElement('button');
    nextBtn.textContent = '下一页';
    nextBtn.onclick = () => loadHistory(currentPage + 1);
    paginationDiv.appendChild(nextBtn);
}

// 添加到历史记录容器底部
const container = document.getElementById('historyList');
container.appendChild(paginationDiv);
}
    // HTML转义函数，防止XSS
    function escapeHtml(unsafe) {
        if (typeof unsafe !== 'string') return unsafe;
        return unsafe
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }

    // 页面加载时获取历史记录
    document.addEventListener('DOMContentLoaded', function() {
        updateModeIndicator();
        loadHistory();
    });
</script>
</body>
</html>